g = icc_read (s15f16, offset + 12 + 2 * 0);
return babl_trc_gamma (g);
break;
-
case 3:
-#if 0
- float a,b,c,d,e,f;
- g = icc_read (s15f16, offset + 12 + 2 * 0);
- a = icc_read (s15f16, offset + 12 + 2 * 1);
- b = icc_read (s15f16, offset + 12 + 2 * 2);
- c = icc_read (s15f16, offset + 12 + 2 * 3);
- d = icc_read (s15f16, offset + 12 + 2 * 4);
- e = icc_read (s15f16, offset + 12 + 2 * 5);
- f = icc_read (s15f16, offset + 12 + 2 * 6);
-#endif
- return babl_trc ("sRGB"); // XXX: not true... and I suspect the CIE L* curve might be expressed as this,
- // formula as well, depending on arguments.
+ {
+ float a,b,c,d;
+ g = icc_read (s15f16, offset + 12 + 2 * 0);
+ a = icc_read (s15f16, offset + 12 + 2 * 1);
+ b = icc_read (s15f16, offset + 12 + 2 * 2);
+ c = icc_read (s15f16, offset + 12 + 2 * 3);
+ d = icc_read (s15f16, offset + 12 + 2 * 4);
+ //fprintf (stderr, "%f %f %f %f %f\n", g, a, b, c, d);
+ if (fabs (g - 2.40) < 0.01 &&
+ fabs (a - 26214) < 0.01 &&
+ fabs (b - 0.947875) < 0.01 &&
+ fabs (c - (-3417)) < 0.01)
+ return babl_trc ("sRGB");
+ else
+ return babl_trc_formula_srgb (g, a, b, c, d);
+ }
+ break;
+ case 4:
+ {
+ float a,b,c,d,e,f;
+ g = icc_read (s15f16, offset + 12 + 2 * 0);
+ a = icc_read (s15f16, offset + 12 + 2 * 1);
+ b = icc_read (s15f16, offset + 12 + 2 * 2);
+ c = icc_read (s15f16, offset + 12 + 2 * 3);
+ d = icc_read (s15f16, offset + 12 + 2 * 4);
+ e = icc_read (s15f16, offset + 12 + 2 * 5);
+ f = icc_read (s15f16, offset + 12 + 2 * 6);
+ fprintf (stderr, "%f %f %f %f %f %f %f\n",
+ g, a, b, c, d, e, f);
+ {
+ fprintf (stdout, "unhandled parametric sRGB formula TRC type %i\n", function_type);
+ *error = "unhandled sRGB formula like TRC";
+ return babl_trc_gamma (2.2);
+ }
+ }
break;
default:
+ *error = "unhandled parametric TRC";
fprintf (stdout, "unhandled parametric TRC type %i\n", function_type);
return babl_trc_gamma (2.2);
break;
icc_write (u32, state->o + 4, 0);
icc_write (u32, state->o + 8, 0);
break;
- case BABL_TRC_GAMMA:
+ case BABL_TRC_FORMULA_GAMMA:
icc_allocate_tag (state, name, 14);
icc_write (sign, state->o, "curv");
icc_write (u32, state->o + 4, 0);
icc_write (u32, state->o + 8, 1);
icc_write (u8f8, state->o + 12, trc->gamma);
break;
+ case BABL_TRC_GAMMA_1_8:
+ icc_allocate_tag (state, name, 14);
+ icc_write (sign, state->o, "curv");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (u32, state->o + 8, 1);
+ icc_write (u8f8, state->o + 12, 1.8);
+ break;
+ case BABL_TRC_GAMMA_2_2:
+ icc_allocate_tag (state, name, 14);
+ icc_write (sign, state->o, "curv");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (u32, state->o + 8, 1);
+ icc_write (u8f8, state->o + 12, 2.2);
+ break;
+ case BABL_TRC_LUT:
+ icc_allocate_tag (state, name, 13 + trc->lut_size * 2);
+ icc_write (sign, state->o, "curv");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (u32, state->o + 8, trc->lut_size);
+ {
+ int j;
+ for (j = 0; j < trc->lut_size; j ++)
+ icc_write (u16, state->o + 12 + j * 2, (int)(trc->lut[j]*65535.5f));
+ }
+ break;
+ // this is the case catching things not directly representable in v2
case BABL_TRC_SRGB:
+ case BABL_TRC_FORMULA_SRGB:
+// default:
{
int lut_size = 512;
icc_allocate_tag (state, name, 13 + lut_size * 2);
int j;
for (j = 0; j < lut_size; j ++)
icc_write (u16, state->o + 12 + j * 2,
- gamma_2_2_to_linear (j / (lut_size-1.0)) * 65535.5);
+ babl_trc_to_linear ((void*)trc, j / (lut_size-1.0)) * 65535.5);
}
}
- break;
- case BABL_TRC_LUT:
- icc_allocate_tag (state, name, 13 + trc->lut_size * 2);
- icc_write (sign, state->o, "curv");
- icc_write (u32, state->o + 4, 0);
- icc_write (u32, state->o + 8, trc->lut_size);
- {
- int j;
- for (j = 0; j < trc->lut_size; j ++)
- icc_write (u16, state->o + 12 + j * 2, (int)(trc->lut[j]*65535.5f));
- }
- break;
- default:
- icc_allocate_tag (state, name, 14);
- icc_write (sign, state->o, "curv");
- icc_write (u32, state->o + 4, 0);
- icc_write (u32, state->o + 8, 1);
- icc_write (u8f8, state->o + 12, trc->gamma);
- break;
}
}
return expf (y * logf (x));
}
-static inline float _babl_trc_gamma_to_linear (const Babl *trc_, float value)
-{
- BablTRC *trc = (void*)trc_;
- return babl_powf (value, trc->gamma);
-}
-
static inline void _babl_trc_gamma_to_linear_buf (const Babl *trc_, const float *in, float *out, int in_gap, int out_gap, int components, int count)
{
return babl_powf (value, trc->rgamma);
}
+static inline float _babl_trc_gamma_to_linear (const Babl *trc_, float value)
+{
+ BablTRC *trc = (void*)trc_;
+ return babl_powf (value, trc->gamma);
+}
+
+static inline float _babl_trc_formula_srgb_from_linear (const Babl *trc_, float value)
+{
+ BablTRC *trc = (void*)trc_;
+ float x= value;
+ float g = trc->lut[0];
+ float a = trc->lut[1];
+ float b = trc->lut[2];
+ float c = trc->lut[3];
+ float d = trc->lut[4];
+ if (x > c * d) // XXX: verify that this math is the correct inverse
+ {
+ float v = babl_powf (x, 1.0/g);
+ v = (v-b)/a;
+ return v;
+ }
+ return x / c;
+}
+
+static inline float _babl_trc_formula_srgb_to_linear (const Babl *trc_, float value)
+{
+ BablTRC *trc = (void*)trc_;
+ float x= value;
+ float g = trc->lut[0];
+ float a = trc->lut[1];
+ float b = trc->lut[2];
+ float c = trc->lut[3];
+ float d = trc->lut[4];
+
+ if (x >= d)
+ {
+ return babl_powf (a * x + b, g);
+ }
+ return c * x;
+}
+
+
static inline float _babl_trc_gamma_1_8_to_linear (const Babl *trc_, float x)
{
if (x >= 0.01f && x < 0.7f)
trc_db[i].fun_from_linear_buf = _babl_trc_linear_buf;
trc_db[i].fun_to_linear_buf = _babl_trc_linear_buf;
break;
- case BABL_TRC_GAMMA:
+ case BABL_TRC_FORMULA_GAMMA:
trc_db[i].fun_to_linear = _babl_trc_gamma_to_linear;
trc_db[i].fun_from_linear = _babl_trc_gamma_from_linear;
trc_db[i].fun_to_linear_buf = _babl_trc_gamma_to_linear_buf;
trc_db[i].fun_from_linear_buf = _babl_trc_gamma_from_linear_buf;
break;
+ case BABL_TRC_FORMULA_SRGB:
+ trc_db[i].lut = babl_calloc (sizeof (float), 5);
+ {
+ int j;
+ for (j = 0; j < 5; j++)
+ trc_db[i].lut[j] = lut[j];
+ }
+ trc_db[i].fun_to_linear = _babl_trc_formula_srgb_to_linear;
+ trc_db[i].fun_from_linear = _babl_trc_formula_srgb_from_linear;
+ break;
case BABL_TRC_GAMMA_2_2:
trc_db[i].fun_to_linear = _babl_trc_gamma_2_2_to_linear;
trc_db[i].fun_from_linear = _babl_trc_gamma_2_2_from_linear;
return;
}
+const Babl *
+babl_trc_formula_srgb (double gamma, double a, double b, double c, double d)
+{
+ char name[32];
+ int i;
+ float params[5]={gamma, a, b, c, d};
+
+ sprintf (name, "%.6f %.6f %.4f %.4f %.4f", gamma, a, b, c, d);
+ for (i = 0; name[i]; i++)
+ if (name[i] == ',') name[i] = '.';
+ while (name[strlen(name)-1]=='0')
+ name[strlen(name)-1]='\0';
+ return babl_trc_new (name, BABL_TRC_FORMULA_SRGB, gamma, 0, params);
+}
+
const Babl *
babl_trc_gamma (double gamma)
{
if (name[i] == ',') name[i] = '.';
while (name[strlen(name)-1]=='0')
name[strlen(name)-1]='\0';
- return babl_trc_new (name, BABL_TRC_GAMMA, gamma, 0, NULL);
+ return babl_trc_new (name, BABL_TRC_FORMULA_GAMMA, gamma, 0, NULL);
}
void